package cn.tedu.tmall.front.mall.dao.repository.impl;

import cn.tedu.tmall.front.mall.dao.repository.ICartCacheRepository;
import cn.tedu.tmall.front.mall.pojo.po.CartCachePO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.*;

@Repository
@Slf4j
public class CartCacheRepository implements ICartCacheRepository {
    @Autowired
    private RedisTemplate<String, Serializable> redisTemplate;

    @Override
    public void add(Long userId, CartCachePO cartCachePO) {
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        String cartKey = getCartKey(userId);
        //拆分前的添加方法
//        String hashKey = cartCachePO.getGoodsId().toString();
//        hashOperations.put(cartKey,hashKey,cartCachePO);
        //大key cartKey  已经保存了用户id
        //构造小key 1_num -> num
        log.debug("cartCachePO:{}",cartCachePO);

        String goodsNumHashKey = getGoodsNumHashKey(cartCachePO.getGoodsId());
        String goodsCheckedHashKey = getGoodsCheckedHashKey(cartCachePO.getGoodsId());
        String goodsInfoHashKey = getGoodsInfoHashKey(cartCachePO.getGoodsId());
        Map<String,Object> smllMap = new HashMap();
        smllMap.put(goodsNumHashKey,cartCachePO.getGoodsNum());
        smllMap.put(goodsCheckedHashKey,cartCachePO.getChecked());
        smllMap.put(goodsInfoHashKey,cartCachePO);
//        smllMap.forEach((k,v)->{
//            System.out.println(k + ":" + v);
//
//        });
        hashOperations.putAll(cartKey,smllMap);
    }

    public List<CartCachePO> list(Long userId) {
        // List<CartCachePO> cartCachePOS = listRaw(userId);
        List<CartCachePO> cartCachePOS = listNew(userId);
        return cartCachePOS;
    }
    /**
     * 拆分获得全部数据
     * @param userId
     * @return
     */
    public List<CartCachePO> listNew(Long userId) {
        String cartKey = getCartKey(userId);
        List<CartCachePO> cartCachePOS = new ArrayList<>();
        HashOperations<String, String, Object> hashOperations = redisTemplate.opsForHash();
        Map<String, Object> entries = hashOperations.entries(cartKey);
        if(!CollectionUtils.isEmpty(entries)) {
            entries.forEach((k,v)-> {
                //先取出第一次的数据
                if(k.contains("Info")) {
                    CartCachePO cachePO =(CartCachePO)v;
                    //更新最新数据
                    Long goodsId = cachePO.getGoodsId();
                    CartCachePO cacheUpdatePO = updateCachePO(userId,goodsId,cachePO);
                    System.out.println(cacheUpdatePO);
                    cartCachePOS.add(cacheUpdatePO);
                }
            });
        }

        return cartCachePOS;
    }

    /**
     * 更新数据
     * @param useId
     * @param goodsId
     * @return
     */
    private CartCachePO updateCachePO(Long useId, Long goodsId,CartCachePO cartCachePO) {
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        String cartKey = getCartKey(useId);
        String goodsCheckedHashKey = getGoodsCheckedHashKey(goodsId);
        String goodsNumHashKey = getGoodsNumHashKey(goodsId);
        CartCachePO newCachePO = new CartCachePO();
        BeanUtils.copyProperties(cartCachePO,newCachePO);
        //获取最新数据
        Integer num = (Integer)hashOperations.get(cartKey, goodsNumHashKey);
        Integer selected = (Integer)hashOperations.get(cartKey, goodsCheckedHashKey);
        newCachePO.setGoodsNum(num);
        newCachePO.setChecked(selected);
        return newCachePO;
    }
    /**
     * 没有拆分获得全部数据
     * @param userId
     * @return
     */
    private  List<CartCachePO> listRaw(Long userId) {
        String cartKey = KEY_PREFIX_MALL_CART + userId;
        List<CartCachePO> cartCachePOS = new ArrayList<>();
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        Map<Object, Object> entries = hashOperations.entries(cartKey);
        entries.forEach((k,v)-> {
            System.out.println(k+":"+v);
            CartCachePO cartCachePO =  (CartCachePO)v;
            cartCachePOS.add(cartCachePO);
        });

        return cartCachePOS;
    }


    @Override
    public void modifyOrReplaceGoodNum(Long userId, Long goodsId, Integer goodsNumber,boolean isReplace) {
        String cartKey = getCartKey(userId);
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        String goodsNumHashKey = getGoodsNumHashKey(goodsId);
        if (isReplace) {
            hashOperations.put(cartKey,goodsNumHashKey,goodsNumber);
        }else {
            //拆分后增加商品数量
            hashOperations.increment(cartKey,goodsNumHashKey,goodsNumber);
        }
    }

    @Override
    public void incrRaw(Long userId, Long goodsId, Integer goodsNumber) {
        String cartKey = getCartKey(userId);
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        //拆分前增加商品数量
        String hashKey = goodsId.toString();
        CartCachePO cartCachePO = (CartCachePO)hashOperations.get(cartKey, hashKey);
        cartCachePO.setGoodsNum(cartCachePO.getGoodsNum()+goodsNumber);
        hashOperations.put(cartKey,hashKey,cartCachePO);

    }

    /**
     * 选择商品
     * @param userId
     * @param goodsId
     */
    @Override
    public void pick(Long userId, Long goodsId) {
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        String cartKey = getCartKey(userId);
        String goodsCheckedHashKey = getGoodsCheckedHashKey(goodsId);
        hashOperations.put(cartKey,goodsCheckedHashKey,1);
    }

    /**
     * 取消选择商品
     * @param userId
     * @param goodsId
     */
    @Override
    public void pickoff(Long userId, Long goodsId) {
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        String cartKey = getCartKey(userId);
        String goodsCheckedHashKey = getGoodsCheckedHashKey(goodsId);
        //修改goodsInfoHashKey中的数据
        String goodsInfoHashKey = getGoodsInfoHashKey(goodsId);
        CartCachePO cartCachePO = (CartCachePO)hashOperations.get(cartKey,goodsInfoHashKey);
        cartCachePO.setChecked(0);
        hashOperations.put(cartKey,goodsInfoHashKey,cartCachePO);

        //修改redis中的数据
        hashOperations.put(cartKey,goodsCheckedHashKey,0);
    }

    @Override
    public void deleteByUserIdAndGoodsId(Long userId, Long goodsId) {
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
        String cartKey = getCartKey(userId);
        String goodsNumHashKey = getGoodsNumHashKey(goodsId);
        String goodsCheckedHashKey = getGoodsCheckedHashKey(goodsId);
        String goodsInfoHashKey = getGoodsInfoHashKey(goodsId);
        hashOperations.delete(cartKey,goodsCheckedHashKey,goodsNumHashKey,goodsInfoHashKey);
    }

    /**
     * 返回购物车小key
     * @param goodsId
     * @return
     */
    private String getGoodsNumHashKey(Long goodsId) {
        return goodsId +"_Num";
    }
    private String getGoodsCheckedHashKey(Long goodsId) {
        return goodsId +"_checked";
    }
    private String getGoodsInfoHashKey(Long goodsId) {
        return goodsId +"_Info";
    }

    /**
     * 返回购物车大key
     * @param userId
     * @return
     */
    private String getCartKey(Long userId) {
        return KEY_PREFIX_MALL_CART + userId;
    }
}
